<script setup lang="ts">
import type { SelectValue } from 'ant-design-vue/es/select';

import { computed, ref } from 'vue';

import { ApiComponent } from '@vben/common-ui';

import { useQuery } from '@tanstack/vue-query';
import { Select } from 'ant-design-vue';

import { createApiFunction } from '#/util/tool';

const props = withDefaults(
  defineProps<{
    api: ((arg?: any) => Promise<any[] | Record<string, any>>) | string;
    cache?: boolean;
    keywords?: string; // 关键字
    params?: Record<string, any>;
    // 请求方式
    requestMethod?: 'get' | 'post';
    searchKeys?: string; // 关键字对应的列名
    showSearch?: boolean;
    value?: SelectValue;
  }>(),
  {
    keywords: undefined,
    params: {} as any,
    requestMethod: 'post',
    showSearch: false,
    searchKeys: undefined,
    value: undefined,
    cache: false,
  },
);

const emit = defineEmits<{
  (e: 'update:value', value: SelectValue | undefined): void;
}>();

const value = computed({
  get() {
    return props.value;
  },
  set(val) {
    emit('update:value', val);
  },
});

defineExpose({
  getValue() {
    return value.value;
  },
});
const searchValue = ref('');
const handleSearch = (value: string) => {
  searchValue.value = value;
};
const fetchQueryFn = () => {
  const params = {
    ...props.params,
    keywords: searchValue.value,
    searchKeys: props.searchKeys,
  };
  return createApiFunction(props.api, props.requestMethod)(params);
};

const { promise: fetchDataFn } = useQuery({
  experimental_prefetchInRender: true,
  queryFn: fetchQueryFn,
  queryKey: [
    'api-select',
    props.api,
    JSON.stringify(props.params || {}),
    searchValue.value,
    props.searchKeys,
  ],
  // refetchOnMount: 'always',
  staleTime: 1000 * 60 * 5,
});
async function fetchOptions() {
  return await fetchDataFn.value;
}
</script>
<template>
  <ApiComponent
    :api="
      props.cache
        ? fetchOptions
        : createApiFunction(props.api, props.requestMethod)
    "
    v-model="value"
    model-prop-name="value"
    loading-slot="suffixIcon"
    visible-event="onDropdownVisibleChange"
    class="w-full"
    :show-search="showSearch"
    @search="handleSearch"
    :params="{
      ...params,
      keywords: searchValue,
      searchKeys,
    }"
    :filter-option="showSearch ? false : undefined"
    :component="Select"
  />
</template>
<style lang="scss" scoped></style>
